Re: rtld + static linking

2003-11-28 Thread Terry Lambert
Marcel Moolenaar wrote:
> On Thu, Nov 27, 2003 at 03:41:14AM -0800, Terry Lambert wrote:
> > > If you can get gcc and binutils to add the necessary support, then
> > > we can talk further. Until then it's academic.
> >
> > I think there are political reasons for not doing this.  The
> > number one reason would be that you could load GPL'ed code as
> > a module into a non-GPL'ed program, and then use it without
> > neding to change your own license to GPL.
> 
> The use of dlopen() does not circumvent that you're creating a
> modified version. The GPL-incompatible code and the GPL code do
> not communicate at arms length. Hence, the GPL-incompatible code
> is to be relicensed if the modified work is to be distributed.

No.  IF you separately distibute your code and the GPL'ed module
code, AND you have an alternate user of the interface, THEN you
can distribute the code at will without GPL'ing it, even if the
intent is to link against the GPL'ed code at runtime.  Be, Inc.
did this with GPL'd Linux device drivers, and the one lawsuit the
FSF began to bring on the basis of a GPL'ed library was resolved
when the authors of the original code provided their own non-GPL'ed
library, thus putting the GPL'ed code at arms length, legally, with
regard to whether or not the combined code was a derivative work of
the GPL'ed code.

Like it or not, being able to dlopen a GPL'ed module means that you
can circumvent the intent of the GPL.  In fact, there are a number
of PAM modules that are GPL'ed (go ahead and check).


> Alternatively, ask the license holder for an exception or see if
> the library can be relicensed under the LGPL.

Why ask, when you can simply circumvent?  The only thing it would
buy you is the ability to not redistribute "modularized source",
which is of questionable benefit.

> From a GPL licensing point of view dlopen() is no different than
> static linking.

Incorrect.  The linking occurs at the behest of the person running
the program, rather than at the behest of the person distributing
the program,.  As distributed, the program and the module together
constitute a "mere agregation", and therefore the program itself is
not subject to the module's GPL nature.


> > Well, it specifically mentions being able to do something like
> > linking libc to libresolv, so that you implicitly get the resolver
> > library when you explicitly link in the C library. That doesn't
> > work with static linking of ELF binaries, so I think we can either
> > say static linking is completely broken and needs to be fixed before
> > it is allowed to be used, or static linking is undefined by the ELF
> > standard.
> 
> Recording dependencies in ELF files is specific to dynamic linking.

No, it's specific to all relocatable ELF objects, at least according
to the specification.

> In fact, there's nothing that you need to add to ELF headers or
> sections to make static linking work. It's irrelevant to an ELF
> specification. That's why it's not mentioned. Dynamic linking needs
> special headers and/or sections in the ELF file to make it work.
> 
> I don't think you can infer from the ELF specification that static
> linking is undefined.

I don't think that you can infer that it's defined.  8-).  Anything
that's not defined is, by definition, undefined.

-- Terry
___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "[EMAIL PROTECTED]"


Re: rtld + static linking

2003-11-27 Thread Marcel Moolenaar
On Thu, Nov 27, 2003 at 03:41:14AM -0800, Terry Lambert wrote:

> > If you can get gcc and binutils to add the necessary support, then
> > we can talk further. Until then it's academic.
> 
> I think there are political reasons for not doing this.  The
> number one reason would be that you could load GPL'ed code as
> a module into a non-GPL'ed program, and then use it without
> neding to change your own license to GPL.

The use of dlopen() does not circumvent that you're creating a
modified version. The GPL-incompatible code and the GPL code do
not communicate at arms length. Hence, the GPL-incompatible code
is to be relicensed if the modified work is to be distributed.i
Alternatively, ask the license holder for an exception or see if
the library can be relicensed under the LGPL.

>From a GPL licensing point of view dlopen() is no different than
static linking.

> > > I'll also point out that the ELF specification does not define static
> > > linking *at all*.
> > 
> > I think that's because it doesn't need any special mention.
> 
> Well, it specifically mentions being able to do something like
> linking libc to libresolv, so that you implicitly get the resolver
> library when you explicitly link in the C library. That doesn't
> work with static linking of ELF binaries, so I think we can either
> say static linking is completely broken and needs to be fixed before
> it is allowed to be used, or static linking is undefined by the ELF
> standard.

Recording dependencies in ELF files is specific to dynamic linking.
In fact, there's nothing that you need to add to ELF headers or
sections to make static linking work. It's irrelevant to an ELF
specification. That's why it's not mentioned. Dynamic linking needs
special headers and/or sections in the ELF file to make it work.

I don't think you can infer from the ELF specification that static
linking is undefined.

-- 
 Marcel Moolenaar USPA: A-39004  [EMAIL PROTECTED]
___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "[EMAIL PROTECTED]"


Re: rtld + static linking

2003-11-27 Thread Mark Murray
Terry Lambert writes:
> > I've looked without much success. Could you give a timeframe, a subject
> > and/or something?
> 
> Note that the part you snipped indicated that the patches were
> posted by a third party, and that my own patches had been offered,
> but were not posted in their entirety to the mailing list.  In
> actuality, I only ever posted portions of my own patches, since
> they also required compiler and linker changes.

Could you please post your patches in their entirety?

M
--
Mark Murray
iumop ap!sdn w,I idlaH
___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "[EMAIL PROTECTED]"


Re: rtld + static linking

2003-11-27 Thread Terry Lambert
Marcel Moolenaar wrote:
> > Ether way, you still need to deal with the linker changes necessary
> > to export the symbol set for all statically linked objects, and to
> > force the inclusion of all archive members when statically linking,
> > if one of the linked libraries is libdl, if you wanted a full
> > implementation.
> 
> I think the cure is worse than the decease in this case. You don't
> want the full libc linked into a static sh, simply because we need
> to be able to load a shared library at runtime.

The alternative is to create a version association between the
libc.a and libc.so, to allow it to be recovered at runtime.  I
don't know how satisfying this would be, but it would resolve
99.9% of the cases, I think.  Arguing against inclusion of
everything for all static libraris without a shared counterpart,
and for the main program, is harder.  For my money, it's a lot
easier to dynamically link everything, and only deal with one
type of executable image thereafter.


> If you can get gcc and binutils to add the necessary support, then
> we can talk further. Until then it's academic.

I think there are political reasons for not doing this.  The
number one reason would be that you could load GPL'ed code as
a module into a non-GPL'ed program, and then use it without
neding to change your own license to GPL.  Editorially, the
FSF compiler folks have some incentive for making dlopen()
inconvenient/difficult to use.  If you link dynamic, at
least they get the LGPL behaviour for all your other libraries
as a consolation prize, so making it work is probably on their
list of "Things To Not Do".

If the Linux people want to be SUSv3/POSIX/IEEE 1003.1-2003
compliant, they'll do the work and FreeBSD will get it for
free.  If thy don't want to do the work, FreeBSD will have to
decide whether they want to carry around local patches, or if
the feature (killing off static vs. dynamic bikesheds) is
worth the effort.

I'm just offering a potential option that's not one of the two
hotly contested ones, as a less controversial approach to a
solution to the original problem.  It's the solution that was
chosen for the original problem that has everyone up in arms,
so a different solution seemed to be called for here...


> > BTW: IEEE 1003.1-2003 requires a full implementation of dlopen, and
> > does not permit an exception for statically linked binaries:
> >
> > http://www.opengroup.org/onlinepubs/007904975/functions/dlopen.html
> 
> Yes it does:
> 
> \begin{quote}
> ... Implementations may also impose specific constraints on the
> construction of programs that can employ dlopen() and its related
> services.
> \end{quote}

The phrase "constraints on the construction of programs" sounds
to me like you're allowed to require compile options, not you're
allowed to make it not work as it's documented to work otherwise,
or we might as well say that calling dlopen() in a given system's
implementation is allowed to invoke nethack, like the original
GCC implementation of "#pragma" did.  8-).


> > I'll also point out that the ELF specification does not define static
> > linking *at all*.
> 
> I think that's because it doesn't need any special mention.

Well, it specifically mentions being able to do something like
linking libc to libresolv, so that you implicitly get the resolver
library when you explicitly link in the C library.  That doesn't
work with static linking of ELF binaries, so I think we can either
say static linking is completely broken and needs to be fixed before
it is allowed to be used, or static linking is undefined by the ELF
standard.


> Note that staticly linked executables can be in violation of platform
> runtime specifications.

A good reason to outlaw them: undefined behaviour sucks.

-- Terry
___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "[EMAIL PROTECTED]"


Re: rtld + static linking

2003-11-27 Thread Terry Lambert
Mark Murray wrote:
> Terry Lambert writes:
> > Since I have patches to make dlopen work with static binaries, and
> [ snip ]
> > As to inevitable "where are the patches?", please check the -current
> > list archives, you will find at least one set there.
> 
> I've looked without much success. Could you give a timeframe, a subject
> and/or something?

Note that the part you snipped indicated that the patches were
posted by a third party, and that my own patches had been offered,
but were not posted in their entirety to the mailing list.  In
actuality, I only ever posted portions of my own patches, since
they also required compiler and linker changes.

Here is the reference for Max Khon's patches, which were posted,
by reference, in their entirety:

| Date:  Tue, 5 Nov 2002 13:21:42 +0600
| From:  Max Khon <[EMAIL PROTECTED]>
| To:Jake Burkholder <[EMAIL PROTECTED]>
| Cc:[EMAIL PROTECTED]
| Subject:   Re: libc size
| 
|http://docs.freebsd.org/cgi/getmsg.cgi?fetch=379714+0+archive/2002/freebsd-current/20021110.freebsd-current

Portions of my patches were posted as part of the discussion
which took place in the same thread.  There did not seem to be
much buy-in on the idea of modifying the compiler tools.

The context of the discussion was for dealing with moving the
resolver and other things out of libc, so that they could be
more easily upgraded.

For the purposes of handling PAM/NSS modules, Max's patches
would work to move everything back to a static linking footing.

FWIW, I dislike this idea, since static ELF libraries do not
properly link against other static ELF libraries, and that type
of chaning only works for dynamically linked ELF libraries (for
no good reason).

-- Terry
___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "[EMAIL PROTECTED]"


Re: rtld + static linking

2003-11-26 Thread Marcel Moolenaar
On Wed, Nov 26, 2003 at 04:16:06AM -0800, Terry Lambert wrote:
> > 
> > Dynamic linking works because the kernel loads and runs the dynamic
> > linker when it sees that the executable defines an interpeter.
> 
> Since I have patches to make dlopen work with static binaries, and
> it doesn't work this way, I must conclude you have not really looked
> deeply into solving the problem.

True. I did not look at aout.

> In any case, I point you to /usr/src/lib/csu/i386/crt0.c, which
> contains these lines of code:

This is aout specific code, not ELF code.

> Ether way, you still need to deal with the linker changes necessary
> to export the symbol set for all statically linked objects, and to
> force the inclusion of all archive members when statically linking,
> if one of the linked libraries is libdl, if you wanted a full
> implementation.

I think the cure is worse than the decease in this case. You don't
want the full libc linked into a static sh, simply because we need
to be able to load a shared library at runtime.

If you can get gcc and binutils to add the necessary support, then
we can talk further. Until then it's academic.

> BTW: IEEE 1003.1-2003 requires a full implementation of dlopen, and
> does not permit an exception for statically linked binaries:
> 
> http://www.opengroup.org/onlinepubs/007904975/functions/dlopen.html

Yes it does:

\begin{quote}
... Implementations may also impose specific constraints on the
construction of programs that can employ dlopen() and its related
services.
\end{quote}

> I'll also point out that the ELF specification does not define static
> linking *at all*.

I think that's because it doesn't need any special mention.

Note that staticly linked executables can be in violation of platform
runtime specifications.

-- 
 Marcel Moolenaar USPA: A-39004  [EMAIL PROTECTED]
___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "[EMAIL PROTECTED]"


Re: rtld + static linking

2003-11-26 Thread Mark Murray
Terry Lambert writes:
> Since I have patches to make dlopen work with static binaries, and
:
[ snip ]
:
> As to inevitable "where are the patches?", please check the -current
> list archives, you will find at least one set there.

I've looked without much success. Could you give a timeframe, a subject
and/or something?

M
--
Mark Murray
iumop ap!sdn w,I idlaH
___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "[EMAIL PROTECTED]"


Re: rtld + static linking

2003-11-26 Thread Terry Lambert
Marcel Moolenaar wrote:
> On Tue, Nov 25, 2003 at 05:44:18PM -0800, Terry Lambert wrote:
> > "E.B. Dreger" wrote:
> > > Dynamic linking works by the kernel running the dynamic linker,
> > > which loads shared objects and fixes the symbol tables, yes?
> >
> > No.
> >
> > Dynamic linking works because the crt0 mmap's the /usr/libexec/ld.so
> > file as executable, and then points known stub offsets into it.
> 
> No.
> 
> Dynamic linking works because the kernel loads and runs the dynamic
> linker when it sees that the executable defines an interpeter.

Since I have patches to make dlopen work with static binaries, and
it doesn't work this way, I must conclude you have not really looked
deeply into solving the problem.

While the ELF specification, and the SVID III, specifically set
aside "enough space" that you can leave the first page unmapped
and have room for the kernel to load in the ld.so (and thereby
save yourself recreating that part of the address space on exec
of non-setuid/setgid binaries, where it's not a security issue),
FreeBSD doesn't do this.  I can only conclude that either no one
has gotten around to it since I pointed it out 6 years ago, or
someone is intent on FreBSD's "exec" beinbg slower than it needs
to be.

In any case, I point you to /usr/src/lib/csu/i386/crt0.c, which
contains these lines of code:

[...]
/* Map in ld.so */
crt.crt_ba = (int)_mmap(0, hdr.a_text,
PROT_READ|PROT_EXEC,
MAP_FILE|MAP_PRIVATE,
crt.crt_ldfd, N_TXTOFF(hdr));
[...]


> A complete executable (i.e. staticly linked) does not export any
> symbols, or at least not in the same way a shared executable and
> shared libraries do.

This is why I keep saying that compiler work would be needed to
export symbols from the original binary and any statically linked
libraries.


> If I try to dynamicly link libbar into a
> complete executable foo and libbar depends on libc, then there's
> no guarantee that all the required bits from libc are in foo,

Correct, for the current (flawed) implementation of the linker.


> nor is there any guarantee that the bits are actually visible or even
> accessable (no linkage table).

In fact, there is a guaranteed that they are not there, for the
current (flawed) implementation of the linker.


> Dynamicly loading libc for use by libbar can work, but it's not
> guaranteed. One failure mode is suddenly having two instances of
> a common variable instead of one. Another is the clobbering of
> data caused reinitializations.

The first problem is a non-issue, at least for FreeBSD supplied
libraries.  For other libraries, yes, it could be an issue.

The second is always a non-issue, since the loading of shared
objects occurs in a hierarchy, and you are perfectly allowed to
have multiple instances of different versions of shared objects
existing simultaneously.  In fact, if you read the dlsym(3) manual
page, you will see that there exists a special handle identifier,
RTLD_NEXT, specifically to enable a program to traverse this
hierarchy in order to obtain the correct symbol.  If you are still
interested in the details of obtaining the correct subhierarchy
from an arbitrary graph of such hierarchies, the way in which this
is normally accomplished is to look for a symbol at your own
hierarchy level, for which the address is known (since both the
program iterating and the symbol you are looking for come from the
same .so file and can be compared), and thereafter descend into
your own branch to find the symbol in queation.


> So, the problem of dynamic linking a shared library into a static
> process is non-trivial and probably cannot be solved genericly.

And yet both Solaris and SVR4 manage to accomplish this.  Of course,
they are not using the crt0.o code supplied by the GCC people, who
have so far failed to ship a set of tools (gcc, binutils) that can
do the job.

The problem can be resolved generically.


> Under restricted and controlled conditions you can make it work.
> I would call it the ability to have plugins, not the ability to
> load dynamic libraries.

Then you are probaly using the implementation that was posted to
-current about half a year ago, which failed to take into account
the symbol sets, and made no changes to the constructor argument
list.

If you look in crt0.c again, you will see a number of lines that
look like this:

#ifdef DYNAMIC
/* ld(1) convention: if DYNAMIC = 0 then statically linked */
/* sometimes GCC is too smart/stupid for its own good */
x = (caddr_t)&_DYNAMIC;
if (x)
__do_dynamic_link(argv);
#endif /* DYNAMIC */

This is the conditional compilation unit for the dynamic crt0.o, as
the same source file is use for both dynamic and static linking.

The value of 'x' and 'argv' in this case are, for the first, the
location of the 'struct _dynamic' that's is used to gate the call
to __do_dynamic_link(), and the enviro

Re: rtld + static linking

2003-11-25 Thread Marcel Moolenaar
On Tue, Nov 25, 2003 at 05:44:18PM -0800, Terry Lambert wrote:
> "E.B. Dreger" wrote:
> > After watching the recent shared/dynamic threads, and reading the
> > archives from five or six years ago, I have a question...
> > 
> > Dynamic linking works by the kernel running the dynamic linker,
> > which loads shared objects and fixes the symbol tables, yes?
> 
> No.
> 
> Dynamic linking works because the crt0 mmap's the /usr/libexec/ld.so
> file as executable, and then points known stub offsets into it.

No.

Dynamic linking works because the kernel loads and runs the dynamic
linker when it sees that the executable defines an interpeter.

> > Is there some reason that a statically-linked program couldn't
> > include some "ld-elf.a" type of intelligence?  Would that be
> > necessary and sufficient to allow statically-linked programs to
> > load shared objects?
> 
> Yes, and yes.

No, and no.

A complete executable (i.e. staticly linked) does not export any
symbols, or at least not in the same way a shared executable and
shared libraries do. If I try to dynamicly link libbar into a
complete executable foo and libbar depends on libc, then there's
no guarantee that all the required bits from libc are in foo, nor
is there any guarantee that the bits are actually visible or even
accessable (no linkage table).
Dynamicly loading libc for use by libbar can work, but it's not
guaranteed. One failure mode is suddenly having two instances of
a common variable instead of one. Another is the clobbering of
data caused reinitializations.

So, the problem of dynamic linking a shared library into a static
process is non-trivial and probably cannot be solved genericly.
Under restricted and controlled conditions you can make it work.
I would call it the ability to have plugins, not the ability to
load dynamic libraries.

-- 
 Marcel Moolenaar USPA: A-39004  [EMAIL PROTECTED]
___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "[EMAIL PROTECTED]"


Re: rtld + static linking

2003-11-25 Thread Terry Lambert
"E.B. Dreger" wrote:
> After watching the recent shared/dynamic threads, and reading the
> archives from five or six years ago, I have a question...
> 
> Dynamic linking works by the kernel running the dynamic linker,
> which loads shared objects and fixes the symbol tables, yes?

No.

Dynamic linking works because the crt0 mmap's the /usr/libexec/ld.so
file as executable, and then points known stub offsets into it.  It
then passes this as part of the environment, at a negative offset,
into the _main, which fills out a little glue table.  After all this
is set up, then _main calls the location .entry in the executable,
which is usally main, but can be set to something else at link time.
This all works because the crt0.o has some self-knowledge for a number
of symbol offsets, and because _main is called with the environment
descriptor.  Basically, the environment descriptor is lost in the
static linking case.


> Is there some reason that a statically-linked program couldn't
> include some "ld-elf.a" type of intelligence?  Would that be
> necessary and sufficient to allow statically-linked programs to
> load shared objects?

Yes, and yes.

The main reason that there is no dlopen is that the environment
descriptor is lost.  This is pretty trivial to remedy, but it
means passing the environment descriptor to something that can
use it to set up the startup.

This is complicated by the fact that only a single .init entry
point is usable, so if you were to override it, you would lose
library initialization for C libraries, and you would fail to
call constructor code for statically declare class instances in
C++ code, and lose out on other linker set stuff, such as per
thread exception stacks, etc..

The trivial fix for this is to add a void * parameter to the
constructor iterator in the crt0, and then pass the environment
there, so that you could implement a libdlopen that took that
and used it to obtain the self-knowledge of the crt0 that was
needed to (1) adjust the stub pointers to an mmap'ed ld.so, and
(2) provide the access to the symbol table needed so that when
you loaded modules, they would link properly vs. the symbols in
the executable itself.  You would either need to change the list
to specifically reference the libc symbols, OR  you would need
to reload libc.so (the problem with doing the latter is that you
might get a different libc out of it, and the executable symbols
that may replace the libc symbols wouldn't do so for modules, so
that's a non-starter).

It's actually a pretty trivial crt0 and ld change to deal with
this, the sticking point is that you have to also change the
libgcc and other GNU code to pass a NULL value to the void *
constructor parameter in the default case.  This would make
the code minorly incompatible with Linux, etc., unless you could
get the GCC people to pick up your change.

-- Terry
___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "[EMAIL PROTECTED]"