[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Static function listed by objdump



Hello,

I think you're seeing an interaction with function descriptors here.
On Itanium, a function is called via a "function descriptor" which has
the address of the function and a value for the "global pointer"
register (which is used as a fixed base for finding offsets against).
It is the callers responsibility to set-up the global pointer before
calling the function.

For speed the PLT calls the function via a copy of the function
pointer in your GOT (fixed up the first time it is called by the
dynamic linker).  Remember, the actual text address of the function
doesn't matter, because it is only valid to call the function with the
GP set correctly, and for that you need a function pointer.

This doesn't really matter until you start taking the address of
functions.  If everybody returns their own cached function descriptor
from their GOT you can never compare the address of functions (which
obviously is not acceptable).

Thus there is the concept of an "official" function descriptor, which
is created when the address of a function is taken by code.

On Mon, Aug 13, 2007 at 11:23:18PM +0200, Raphael Hertzog wrote:
> For instance, take libglib2.0. In the "objdump -T" output I see:
> DYNAMIC SYMBOL TABLE:
[...]
> 00000000000d4d60 l    DF .text  0000000000000290              g_io_unix_get_flags
> 00000000000d4a60 l    DF .text  0000000000000120              g_io_unix_set_flags
> 00000000000d4b80 l    DF .text  0000000000000020              g_io_unix_free
> 00000000000d4ba0 l    DF .text  00000000000000c0              g_io_unix_create_watch
> 00000000000d4c60 l    DF .text  0000000000000100              g_io_unix_close
> 00000000000d4ff0 l    DF .text  00000000000001f0              g_io_unix_seek
> 00000000000d51e0 l    DF .text  0000000000000150              g_io_unix_write
> 00000000000d5330 l    DF .text  0000000000000180              g_io_unix_read
> 00000000000d4820 l    DF .text  0000000000000030              g_io_unix_finalize
> 00000000000d4950 l    DF .text  0000000000000110              g_io_unix_dispatch
> 00000000000d4850 l    DF .text  0000000000000080              g_io_unix_check

Yep, if you have a look at the relocations you will see (readelf
output is slightly more useful here)

$ readelf --relocs  ./libglib-2.0.so

Relocation section '.rela.dyn' at offset 0x117a0 contains 230 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
[...]
000000121d68  000d00000047 R_IA64_FPTR64LSB  00000000000c33c0 g_io_unix_set_flags + 0
000000121d70  000c00000047 R_IA64_FPTR64LSB  00000000000c36c0 g_io_unix_get_flags + 0
[...]

When the dynamic loader sees these relocations, it reserves some space
in its own global function descriptor table and makes the "one true"
official function descriptor.  Then, if somebody else takes the
address of the function this official descriptor can be returned, and
consequently the same function will have the same address, as you
expect.

> When you check the sources of glib, you'll discover that those functions are
> "static" and should thus not be exported. If you check on any other
> architecture, those functions do not appear in objdump's output.

Yes, interesting.  The best I could find is 

http://www.codesourcery.com/archives/cxx-abi-dev/msg01411.html
 
which seems to suggest that for PIC objects, it is quicker to just
have these references fixed up via relocations when the program is
loaded.

You can see in the code (giounix.c) where the structs full of function
descriptors are created; this is in effect taking the address of the
function and causing the relocations and consequent symbols.

---
GSourceFuncs g_io_watch_funcs = {
  g_io_unix_prepare,
  g_io_unix_check,
  g_io_unix_dispatch,
  g_io_unix_finalize
};

static GIOFuncs unix_channel_funcs = {
  g_io_unix_read,
  g_io_unix_write,
  g_io_unix_seek,
  g_io_unix_close,
  g_io_unix_create_watch,
  g_io_unix_free,
  g_io_unix_set_flags,
  g_io_unix_get_flags,
};
---

> Can you explain me that behaviour and is that intended/normal or is that a bug?

It is expected
 
> One might note that all those symbols are flagged "local", does that mean that
> the symbol can only be used within the library and that no app can use it ?

Yes, symbol visibility is still enforced, e.g. if you try and
reference one of those static functions you'll get a linker error.

I hope that explains how the symbol is used within the library.  You
may also notice strange things happening with the Power ABI.  I've
written a little about that when I was looking at it [1], it might come in
handy.

Cheers,

-i

[1] http://www.gelato.unsw.edu.au/IA64wiki/PPC64ABI

Attachment: signature.asc
Description: Digital signature


Reply to: