On Sat, Jul 28, 2001 at 06:26:45PM -0500, David Christian wrote:
> Okay, but I'd really like to have a better understanding...is there
> somewhere I can go to get a good explanation of library format?  I
> looked for some docs on ELF, but I couldn't find anything technical.
> Can you tell me *why* I can't get to a function that is listed as being
> global, just because the header file it is listed in is not given to the
> client?

Dynamically linked libraries[1] (.DLL, .so) contain a table at the start
of the file with the addresses of all exported functions.  ("Exported",
in this case, meaning "made available to the public".)  A program that
uses the function foo() loads the library, searches that table for a
function named foo(), and sees that it's at offset 0xDEADBEEF from the
start of the library.  Pretty easy.

Non-exported functions (even if global to the library) aren't in that
table.  If you want to call them, you have to scan through the compiled
code to find them.  To make matters worse, if the library doesn't
contain debugging information, it probably doesn't even contain the
string "foo", so you'll have to use some other method of identifying
the code which belongs to that function.

The version-specificity comes in because changing the libraries code
is likely to move the function's entry point around (if function bar()
is physically located closer to the start of the library's code than
foo() and it grows by a byte, foo() will then start at 0xDEADBEF0[2]
and jumping to 0xDEADBEEF will probably do Something Bad.)  Changing
the complier settings will probably make entry points shift by larger
amounts even if the source itself isn't changed.

When the function moves around, you've got it easy if it's exported,
because the function table will be updated and you'll get the new
address the next time you look it up.  That's why the table is there.
But if it's not exported, you need to dig out the new entry point
from scratch.

Disclaimer that I forgot to include last time:  I'm not an expert on
library architecture and I don't have any reference materials to verify
this information against, but it is a topic that I've brushed up
against several times.  This is my understanding of it and it makes
enough sense that it's how I would do things if I had to build an
interface of this type from scratch myself.  However, some of the
details may not be 100% accurate.  If anyone spots inaccuracies, I'd
love to have them pointed out.

[1] All of this is essentially true for statically-linked libraries,
but private function access is a little simpler in that case because
of two things:

1) A human is available to inspect the library for the function's
entry point.  Doing this manually isn't likely to be easy (unless the
library contains sufficient debugging information), but it's not nearly
as hard as writing code to do it without human intervention.

2) You know that the library will always be the same version as you
built it against, while dynamic libs can change to a new version when
you aren't looking.

[2] Since the addresses are obviously bogus, I'm ignoring alignment
issues.  In the real world, the entry points would probably be aligned
on dword (4 byte) boundaries.  But the principle remains the same.

-- 
With the arrest of Dimitry Sklyarov it has become apparent that it is not
safe for non US software engineers to visit the United States. - Alan Cox
"To prevent unauthorized reading..."         - Adobe eBook reader license