Hi!

Looking at various /usr/X11R6/lib/lib*.so* shared libraries,
I'm seeing lots of exported symbols which look like they are exported
just because they cannot be static (as they are used by some other .o files
in the same shared library, but never by anything outside).
If these could be classified (e.g. some _X* symbols in libX11.so.6,
some _Ice* symbols in libICE.so.6 etc. might fall into this category),
XFree86 could have smaller and faster shared libraries with less dynamic
relocations, which would not need to set up PIC pointer so often and use
less instructions to access shared library local variables (by bypassing
GOT on some arches).
In recent Linux distros (gcc 3.3+, binutils at most a year old), this 
can be done in two different ways at least:
1) use __attribute__((visibility ("hidden"))) in prototypes of
   functions/variables, which cannot be static, but are never to be
   used outside of the shared libraries which define them
2) use anynymous linker version script, like:
cat > libX11.map <<EOF
{
  global: [a-zA-Z]*; _Xsomesymbolthatneedstobeexported;
          _Xsomeothersymbolwhichneedstobeexported;
  local: *;
};
EOF
gcc ... -shared -Wl,--version-script,libX11.map ...

1) is certainly better, as already the compiler knows which symbols
   will surely be defined in the same shared library and never exported;
   for objects, e.g. on IA-32 it can use @GOTOFF relocations, while
   normally it has to first load object's address from got through @GOT
   relocation, then dereference that address (the former also means
   no runtime relocation, the latter means GOT dynamic relocation).
   For functions, unless their address is being taken instead of
   call, the difference between 1) and 2) is smaller, just that
   PIC register doesn't have to be loaded before the call in 1)
   while it has to be for 2). Without 1) or 2), the call goes
   through .plt, which on IA-32 is call to a stub with indirect
   jump, which the first time it is used does symbol lookup
   plus store into .got.plt.
   On non-IA32, how big the wins varries from architecture to architecture,
   but it is always better than nothing.
   1) could be done by some header which everything uses, doing
   #if defined HAVE_VISIBILITY_ATTRIBUTE && defined __PIC__
   #define hidden __attribute__((visibility ("hidden")))
   #else
   #define hidden /**/
   #endif
   and write prototypes like:
   void hidden someshlibprivateroutine (void);
   extern int someshlibprivatevar hidden;
   etc.

Is there somebody who could cook up lists of private symbols,
at least for the most commonly used shared libraries?
I haven't done this because I don't know XFree86 enough to know what
is considered public interface and what is exported just by accident.
When such list exists and is agreed on, I certainly can cook up patches.

        Jakub
_______________________________________________
Devel mailing list
[EMAIL PROTECTED]
http://XFree86.Org/mailman/listinfo/devel

Reply via email to